using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Collections;
using System.IO;


namespace Athena.Core
{
    public class PartsRegistry
    {
        static string PARTS_FILE = Utility.DocumentsDirectory + "\\AthenaParts.bin";

        static PartsRegistry _oInstance = new PartsRegistry();
        public static PartsRegistry Instance
        {
            get
            {
                return _oInstance;  
            }
        }

        private PartsRegistry() 
        {
            LoadRegistry();
        }

        public List<Athena.Objects.IDrawable> Parts
        {
            get
            {
                List<Athena.Objects.IDrawable> oParts = new List<Athena.Objects.IDrawable>();
                if (_oParts == null || _oParts.Count == 0) return oParts;
                foreach (Athena.Objects.IDrawable oDrawable in _oParts.Values)
                {
                    oParts.Add(oDrawable);
                }                
                return oParts;
            }
        }

        public void LoadRegistry()
        {
            try
            {
                if (File.Exists(PARTS_FILE))
                {
                    FileStream oStream = new FileStream(PARTS_FILE, FileMode.Open);
                    try
                    {
                        System.Runtime.Serialization.Formatters.Binary.BinaryFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                        _oParts = (Hashtable)formatter.Deserialize(oStream);
                        
                    }
                    finally
                    {
                        oStream.Close();
                        
                    }
                }
            }
            catch (Exception)
            {
            }

        }

        public void SaveRegistry()
        {
            try
            {
                FileStream oStream = new FileStream(PARTS_FILE, FileMode.OpenOrCreate);
                try
                {
                    System.Runtime.Serialization.Formatters.Binary.BinaryFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                    formatter.Serialize(oStream, _oParts);

                }
                finally
                {
                    oStream.Close();
                }

                
            }
            catch (Exception)
            {
            }
        }

        Hashtable _oParts = new Hashtable();

        public void RemovePart(string sId)
        {
            _oParts.Remove(sId);
            SaveRegistry();
            OnPartsChanged();
        }


        public void RemoveParts(List<string> oList)
        {
            foreach (string sId in oList)
            {
                _oParts.Remove(sId);
            }
            SaveRegistry();
            OnPartsChanged();
            
        }


        public void AddPart(Athena.Objects.IDrawable oPart)
        {
            // TODO: bummer i need a clone of the drawable but can't easily get one ... .
            // what to do what to do ... 

            Athena.Objects.IDrawable oDrawable = (Athena.Objects.IDrawable)oPart.Clone();

            if (oDrawable.Item == null || String.IsNullOrEmpty(oDrawable.Item.ID))
                return;

            string sId = oDrawable.Item.ID;
            if (_oParts.ContainsKey(sId))
            {
                return;
                //while (_oParts.ContainsKey(sId))
                //{
                //    sId = sId + "_1";
                //    oDrawable.ItemPtr.Name = sId;
                //}
                
            }
            _oParts.Add(sId, oDrawable);

            SaveRegistry();
            OnPartsChanged();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sId">part id</param>
        /// <returns>true if part is in the repository, false otherwise</returns>
        public bool IsPart(string sId)
        {            
            return _oParts.ContainsKey(sId);
        }

        public Athena.Core.Item GetItem(string sId)
        {
            return GetDrawable(sId, new PointF()).Item;
        }

        public Athena.Objects.IDrawable GetDrawable(string sId, System.Drawing.PointF oTarget)
        {
            //Athena.Objects.SpeciesGlyph oGlyph = new Athena.Objects.SpeciesGlyph(oTarget);
            //return oGlyph;

            Athena.Objects.IDrawable oDrawable = (Athena.Objects.IDrawable)_oParts[sId];
            oDrawable.Location = oTarget;
            return oDrawable;
        }

        public delegate void PartsChangedDelegate(object sender, EventArgs e);
        public event PartsChangedDelegate PartsChanged;
        // Invoke the Changed event; called whenever list changes:
        protected virtual void OnPartsChanged()
        {
            if (PartsChanged != null)
            {
                PartsChanged(this, EventArgs.Empty);
            }
        }

    }
}
